
#pragma once

#ifndef _fmbSingleton
#define _fmbSingleton

#include "fmbMutex.h"
#include <cstdlib>

namespace fm {
  namespace base {

template <class T>
class Singleton {

  static Mutex m_mutex;
  static T *m_instance;

private:
  // prevent misuse
  Singleton(const Singleton &source);
  Singleton &operator=(const Singleton &source);

  static void create() {
    m_instance = new T();
    atexit(destroy);
  }

  static void destroy() {
    delete m_instance;
  }

public:

  inline static T &instance() {
    if (m_instance) return *m_instance;
    Locker lock(m_mutex);
    if (m_instance) return *m_instance;
    create();
    return *m_instance;
  }

};

template<class T>
T *Singleton<T>::m_instance = NULL;

template<class T>
Mutex Singleton<T>::m_mutex;


  // end of namespace fm::base
  }
// end of namespace fm
}

#endif
